// https://leetcode.cn/problems/combination-sum/

/*
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ，找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ，并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同，则两种组合是不同的。 

对于给定的输入，保证和为 target 的不同组合数少于 150 个。

输入：candidates = [2,3,6,7], target = 7
输出：[[2,2,3],[7]]

*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;


class Solution {
public:
    vector <vector<int>> res;
    int len = 0;

    vector <vector<int>> combinationSum(vector<int> &candidates, int target) {
        len = candidates.size();
        sort(candidates.begin(), candidates.end());
        for (int i = 0; i < len; i++) {
            vector<int> tmp = {candidates[i]};
            dfs(candidates, tmp, i, target - candidates[i]);
        }
        return res;
    }

    void dfs(vector<int> &candidates, vector<int> &tmp, int index, int target) {
        if (target == 0) {
            res.push_back(tmp);
            return;
        }
        for (int i = index; i < len; i++) {
            if (target - candidates[i] < 0) break;
            target -= candidates[i];
            tmp.push_back(candidates[i]);
            dfs(candidates, tmp, i, target);
            target += candidates[i];
            tmp.pop_back();
        }
    }

};

int main() {
    Solution so;
    vector<int> candidates = {2, 3, 6, 7};
    int target = 7;
    vector <vector<int>> res = so.combinationSum(candidates, target);
    for (auto items : res) {
        for (auto item : items) {
            cout << item << ",";
        }
        cout << endl;
    }
    return 0;
}